//
// 嗨~ o(*￣▽￣*)ブ
// Created by Mokou on 2020/7/14.
//

#import <pthread/pthread.h>
#import "DBManager.h"

@implementation DBManager {
    pthread_mutex_t _mutex;
}

static DBManager *instance;

+ (DBManager *)shareInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] initWithDatabaseName:@"elec_mobile.db"];
    });
    return instance;
}

- (instancetype)initWithDatabaseName:(NSString *)dbFileName {
    self = [super init];
    pthread_mutex_init(&_mutex, NULL);

    if (self) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documents = paths[0];
        NSString *database_path = [documents stringByAppendingPathComponent:dbFileName];
        NSLog(database_path);

        if (sqlite3_open([database_path UTF8String], &db) != SQLITE_OK) {
            sqlite3_close(db);
            NSAssert(NO, @"fail to open database!!!");
        }
    }
    return self;
}

- (void)execSql:(NSString *)sql {
    pthread_mutex_lock(&_mutex);
    char *err;
    if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) {
        NSLog(@"db exec fail! %@", [NSString stringWithUTF8String:err]);
    }
    pthread_mutex_unlock(&_mutex);
}

- (BOOL)insert:(NSString *)tableName valueDict:(NSDictionary *)values {
    NSString *cols = @"";
    NSString *vals = @"";
    for (id key in values) {
        cols = [cols stringByAppendingFormat:@"'%@',", key];
        vals = [vals stringByAppendingFormat:@"'%@',", values[key]];
    }
    NSString *sql = [NSString stringWithFormat:@"insert into %@ (%@) values (%@);", tableName,
                                               [cols substringToIndex:cols.length - 1],
                                               [vals substringToIndex:vals.length - 1]];
    [self execSql:sql];
    return YES;
}

- (NSArray *)searchWithSql:(NSString *)sqlQuery {
    pthread_mutex_lock(&_mutex);
    NSMutableArray *result = [[NSMutableArray alloc] init];
    sqlite3_stmt *statement;
    if (sqlite3_prepare_v2(db, [sqlQuery UTF8String], -1, &statement, nil) == SQLITE_OK) {
        while (sqlite3_step(statement) == SQLITE_ROW) {
            int count = sqlite3_column_count(statement);
            NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
            for (int i = 0; i < count; i++) {
                const char *name = sqlite3_column_name(statement, i);
                int type = sqlite3_column_type(statement, i);
                id value = nil;
                switch (type) {
                       case SQLITE_INTEGER:
                           value = @(sqlite3_column_int64(statement,i));
                           break;
                       case SQLITE_FLOAT:
                           value = @(sqlite3_column_double(statement, i));
                           break;
                       case SQLITE3_TEXT:
                           value = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(statement, i)];
                           break;
                       case SQLITE_BLOB:
                           value = CFBridgingRelease(sqlite3_column_blob(statement, i));
                           break;
                       case SQLITE_NULL:
                           value = @"";
                           break;

                       default:
                           break;
                }

                dict[[NSString stringWithUTF8String:name]] = value;

            }
            [result addObject:dict];
        }
    }
    sqlite3_finalize(statement);
    pthread_mutex_unlock(&_mutex);
    return result;
}

@end
